package interview;

import java.util.Arrays;

/**
 *麻将胡牌问题
 */
public class Main3 {

    public static void main(String[] args) {
        String input = "1122335444789";
        int[] ints = newIndexArray(convertToIntArray(input.toCharArray()));
        System.out.println(Arrays.toString(ints));
        System.out.println(isHuPai(nextIndex(0, ints), ints) ? "yes" : "no");
    }

    public static boolean isHuPai(int index, int[] newcs) {
        //循环每一个位数
        for (int i = index; i < newcs.length; i = nextIndex(index, newcs)) {
            boolean isOk = false;
            for (int j = 0; j < 3; j++) {//三种分法组合
                int[] tmp = copyArray(newcs);
                if (exec(index, j, tmp)) {
                    isOk = isHuPai(nextIndex(index, tmp), tmp);
                    if (isOk) return true;
                }
            }
            if (!isOk) {
                System.out.println("失败");
                return false;
            }
        }
        return isFinish(newcs);
    }

    private static int nextIndex(int index, int[] newcs) {
        for (int i = index + 1; i < newcs.length; i++) {
            if (newcs[i] > 0)
                return i;
        }
        return newcs.length;
    }


    public static boolean exec(int i, int j, int[] newcs) {
        if (j == 0) {
            return shunnzi(newcs, i);
        } else if (j == 1) {
            return kezi(newcs, i);
        } else if (j == 2) {
            return diuzi(newcs, i);
        }
        return false;
    }

    private static int[] copyArray(int[] is) {
        int[] newcs = new int[is.length];
        for (int i = 0; i < is.length; i++) {
            newcs[i] = is[i];
        }
        return newcs;
    }

    private static int[] newIndexArray(int[] is) {
        int[] newcs = new int[getMax(is) + 1];
        for (int i = 0; i < is.length; i++) {
            int index = is[i];
            newcs[index] += 1;
        }
        return newcs;
    }

    private static boolean shunnzi(int[] newcs, int i) {
        if (getByIndex(newcs, i - 1) != 0 && getByIndex(newcs, i) != 0 && getByIndex(newcs, i + 1) != 0) {
            newcs[i] = newcs[i] - 1;
            newcs[i - 1] = newcs[i - 1] - 1;
            newcs[i + 1] = newcs[i + 1] - 1;
            System.out.println(String.format("顺子 %d , %d ,%d ", i - 1, i, i + 1));
            return true;
        }
        if (getByIndex(newcs, i) != 0 && getByIndex(newcs, i + 1) != 0 && getByIndex(newcs, i + 2) != 0) {
            newcs[i] = newcs[i] - 1;
            newcs[i + 1] = newcs[i + 1] - 1;
            newcs[i + 2] = newcs[i + 2] - 1;
            System.out.println(String.format("顺子 %d , %d ,%d ", i, i + 1, i + 2));
            return true;
        }
        if (getByIndex(newcs, i - 2) != 0 && getByIndex(newcs, i - 1) != 0 && getByIndex(newcs, i) != 0) {
            newcs[i] = newcs[i] - 1;
            newcs[i - 1] = newcs[i - 1] - 1;
            newcs[i - 2] = newcs[i - 2] - 1;
            System.out.println(String.format("顺子 %d , %d ,%d ", i - 2, i - 1, i));
            return true;
        }
        return false;
    }

    private static boolean kezi(int[] newcs, int i) {
        if (newcs[i] > 2) {
            newcs[i] = newcs[i] - 3;
            System.out.println(String.format("克子 %d , %d ,%d ", i, i, i));
            return true;
        }
        return false;
    }

    private static boolean diuzi(int[] newcs, int i) {
        if (newcs[i] > 1) {
            newcs[i] = newcs[i] - 2;
            System.out.println(String.format("对子 %d , %d", i, i, i));
            return true;
        }
        return false;
    }

    private static int getByIndex(int[] newcs, int i) {
        if (i < 0 || i >= newcs.length) {
            return 0;
        }
        return newcs[i];
    }

    public static int[] convertToIntArray(char[] cs) {
        int[] array = new int[cs.length];
        for (int i = 0; i < cs.length; i++) {
            array[i] = Integer.valueOf(String.valueOf(cs[i]));
        }
        return array;
    }

    private static boolean isFinish(int[] is) {
        for (int c : is) {
            if (c > 0) {
                return false;
            }
        }
        return true;
    }

    private static int getMax(int[] is) {
        int r = is[0];
        for (int c : is) {
            if (c > r) {
                r = c;
            }
        }
        return r;
    }

}